# 
import argparse
from typing import Dict
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D

class Chp01Sec04S1(object):
    def __init__(self):
        self.name = ''

    @staticmethod
    def startup(params:Dict = {}) -> None:
        print(f'Linear Regression 1 Demo v0.0.1')
        plt.rcParams['figure.figsize'] = [8, 8]
        plt.rcParams.update({'font.size': 18})

        x = 3 # True slope
        a = np.arange(-2,2,0.25)
        a = a.reshape(-1, 1)
        b = x*a + np.random.randn(*a.shape) # Add noise

        plt.plot(a, x*a, color='k', linewidth=2, label='True line') # True relationship
        plt.plot(a, b, 'x', color='r', markersize = 10, label='Noisy data') # Noisy measurements

        U, S, VT = np.linalg.svd(a,full_matrices=False)
        xtilde = VT.T @ np.linalg.inv(np.diag(S)) @ U.T @ b # Least-square fit

        plt.plot(a,xtilde * a,'--',color='b',linewidth=4, label='Regression line')

        plt.xlabel('a')
        plt.ylabel('b')

        plt.grid(linestyle='--')
        plt.legend()
        plt.show()

def main(params:Dict = {}) -> None:
    Chp01Sec04S1.startup(params=params)

def parse_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser()
    parser.add_argument(
        '--run_mode', action='store',
        type=int, default=1, dest='run_mode',
        help='run mode'
    )
    return parser.parse_args()

if '__main__' == __name__:
    args = parse_args()
    params = vars(args)
    main(params=params)